//Copyright (c) 2008, Matthew Newman
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
//* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
//* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
//
//* Neither the name of BestSnowman.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.ComponentModel;
using System.IO;
using System.Linq;
using TaskDialog;
using ProductKeyManager.DB;
using System.Globalization;
using ProductKeyManager.UI;
using System.Data.SqlServerCe;

namespace ProductKeyManager
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public sealed partial class MainWindow : System.Windows.Window, IDisposable
    {
        ProductKeyManagerDB db;
        private IEnumerable<Product> products;

        private string searchText;
        private SortDirection nameSort = SortDirection.None;

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindow"/> class.
        /// </summary>
        public MainWindow()
        {
            if (String.IsNullOrEmpty(Properties.Settings.Default.ConnectionString))
            {
                string appDataFolder = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                Properties.Settings.Default.ConnectionString = "Data Source=" + appDataFolder + "\\pkmdb.sdf";
                Properties.Settings.Default.Save();
                db = new ProductKeyManagerDB(Properties.Settings.Default.ConnectionString);
                if (!db.DatabaseExists())
                {
                    try
                    {
                        db.CreateDatabase();
                    }
                    catch (SqlCeException)
                    {
                        MessageBox.Show("Unable to create db file");
                    }
                }
            }
            InitializeComponent();
            
        }

        /// <summary>
        /// Windows the on loaded.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void WindowOnLoaded(object sender, RoutedEventArgs e)
        {
            LoadResources();
            LoadToolbarLocations();

            if (Properties.Settings.Default.SaveLastSearch && !String.IsNullOrEmpty(Properties.Settings.Default.LastSearch))
            {
                this.txtSearch.Text = Properties.Settings.Default.LastSearch;
                chkSearch.IsChecked = true;
                OnSearch(sender, e);
            }

            nameSort = ParseSortName(Properties.Settings.Default.SortNameDirection);
            OnNameSort(null, e);

            SetView();
        }

        public void LoadResources()
        {
            this.Title = this.LoadStringResource("Title");

            this.MenuFile.Header = this.LoadMenuResource("File");
            this.MenuFileNew.Header = this.LoadMenuResource("FileNew");
            this.MenuFileImport.Header = this.LoadMenuResource("FileImport");
            this.MenuFileExport.Header = this.LoadMenuResource("FileExport");
            this.MenuFileExportPKM.Header = this.LoadMenuResource("FileExportPKM");
            this.MenuFileExportMSDN.Header = this.LoadMenuResource("FileExportMSDN");
            this.MenuFileExit.Header = this.LoadMenuResource("FileExit");

            this.MenuEdit.Header = this.LoadMenuResource("Edit");

            this.MenuView.Header = this.LoadMenuResource("View");
            this.MenuViewSort.Header = this.LoadMenuResource("ViewSort");
            this.MenuViewSortName.Header = this.LoadMenuResource("ViewSortName");
            this.MenuViewSortNameNone.Header = this.LoadMenuResource("ViewSortNameNone");
            this.MenuViewSortNameAsc.Header = this.LoadMenuResource("ViewSortNameAsc");
            this.MenuViewSortNameDsc.Header = this.LoadMenuResource("ViewSortNameDsc");
            this.MenuViewLockToolBars.Header = this.LoadMenuResource("ViewLockToolBars");

            this.MenuTools.Header = this.LoadMenuResource("Tools");
            this.MenuToolsPurgeDB.Header = this.LoadMenuResource("ToolsPurgeDB");
            this.MenuToolsSettings.Header = this.LoadMenuResource("ToolsSettings");

            this.MenuHelp.Header = this.LoadMenuResource("Help");
            this.MenuHelpAbout.Header = this.LoadMenuResource("HelpAbout");

            this.lblAddToolTipTitle.Content = this.LoadStringResource("AddToolTipTitle");
            this.tbAddToolTipText.Text = this.LoadStringResource("AddToolTipText");
            this.lblEditToolTipTitle.Content = this.LoadStringResource("EditToolTipTitle");
            this.tbEditToolTipText.Text = this.LoadStringResource("EditToolTipText");
            this.lblDeleteTooltipTitle.Content = this.LoadStringResource("DeleteToolTipTitle");
            this.tbDeleteToolTipText.Text = this.LoadStringResource("DeleteToolTipText");
            this.lblSearchToolTipTitle.Content = this.LoadStringResource("SearchToolTipTitle");
            this.tbSearchToolTipText.Text = this.LoadStringResource("SearchToolTipText");
            this.lblSearchExampleTitle.Content = this.LoadStringResource("SearchExampleTitle");
            this.tbSearchExampleText.Text = this.LoadStringResource("SearchExampleText");
        }

        /// <summary>
        /// Loads the toolbar locations.
        /// </summary>
        private void LoadToolbarLocations()
        {
            toolAddEditDelete.Band = Properties.Settings.Default.AddEditDeleteBand;
            toolAddEditDelete.BandIndex = Properties.Settings.Default.AddEditDeleteBandIndex;

            toolSearch.Band = Properties.Settings.Default.SearchBand;
            toolSearch.BandIndex = Properties.Settings.Default.SearchBandIndex;

            toolTrayBottom.IsLocked = Properties.Settings.Default.LockToolBars;
            MenuViewLockToolBars.IsChecked = Properties.Settings.Default.LockToolBars;
        }

        /// <summary>
        /// Sets the view.
        /// </summary>
        private void SetView()
        {
            SaveToolbarLocations();

            if (db == null)
            {
                try
                {
                    db = new ProductKeyManagerDB(Properties.Settings.Default.ConnectionString);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
            db.ClearSimilarity();
            products = from p in db.Products
                       select p;

            if (searchText != null)
            {
                // This query orders the products by similarity and hides any product that has zero similarity
                products = from p in products
                           orderby p.GetSimilarity(searchText) descending
                           where p.SearchSimilarity > 0
                           select p;
            }
            else
            {
                switch (nameSort)
                {
                    case SortDirection.Ascending:
                        products = from k in products
                                   orderby k.Name ascending
                                   select k;
                        break;
                    case SortDirection.Descending:
                        products = from k in products
                                   orderby k.Name descending
                                   select k;
                        break;
                    default:
                        break;
                }
            }

            listProdKeys.DataContext = products;
        }

        /// <summary>
        /// Saves the toolbar locations.
        /// </summary>
        private void SaveToolbarLocations()
        {
            Properties.Settings.Default.AddEditDeleteBand = toolAddEditDelete.Band;
            Properties.Settings.Default.AddEditDeleteBandIndex = toolAddEditDelete.BandIndex;

            Properties.Settings.Default.SearchBand = toolSearch.Band;
            Properties.Settings.Default.SearchBandIndex = toolSearch.BandIndex;

            Properties.Settings.Default.LockToolBars = toolTrayBottom.IsLocked;

            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Called when sorting by name.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnNameSort(object sender, RoutedEventArgs e)
        {
            MenuViewSortNameNone.IsChecked = false;
            MenuViewSortNameAsc.IsChecked = false;
            MenuViewSortNameDsc.IsChecked = false;
            if (sender != null)
            {
                nameSort = ParseSortName(((MenuItem)sender).Header.ToString());
            }
            switch (nameSort)
            {
                case SortDirection.None:
                    MenuViewSortNameNone.IsChecked = true;
                    break;
                case SortDirection.Ascending:
                    MenuViewSortNameAsc.IsChecked = true;
                    break;
                case SortDirection.Descending:
                    MenuViewSortNameDsc.IsChecked = true;
                    break;
            }
            SetView();
            Properties.Settings.Default.SortNameDirection = nameSort.ToString();
            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Parses the name of the sort.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        private static SortDirection ParseSortName(string name)
        {
            if (name == UI.WindowExtensions.LoadMenuResource("MainWindow", "ViewSortNameAsc"))
            {
                return SortDirection.Ascending;
            }
            else if (name == UI.WindowExtensions.LoadMenuResource("MainWindow", "ViewSortNameDsc"))
            {
                return SortDirection.Descending;
            }
            else
            {
                return SortDirection.None;
            }
        }

        /// <summary>
        /// Called on search.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnSearch(object sender, RoutedEventArgs e)
        {
            searchText = this.txtSearch.Text.ToLower(CultureInfo.CurrentCulture);
            Properties.Settings.Default.LastSearch = searchText;
            SetView();
            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Called when the search is cleared.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnUnSearch(object sender, RoutedEventArgs e)
        {
            searchText = null;
            Properties.Settings.Default.LastSearch = searchText;
            SetView();
            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Called when the New button is clicked
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void NewButtonClicked(object sender, RoutedEventArgs e)
        {
            ProductDialog newDlg = new ProductDialog();
            newDlg.Owner = this;
            newDlg.ShowDialog();

            if (newDlg.NewProduct != null && !String.IsNullOrEmpty(newDlg.NewProduct.Name))
            {
                db.Products.InsertOnSubmit(newDlg.NewProduct);
                db.SubmitChanges();
            }

            SetView();
        }

        /// <summary>
        /// Called when the Edit button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void EditButtonClicked(object sender, RoutedEventArgs e)
        {
            ProductDialog newDlg = new ProductDialog();
            newDlg.Mode = DialogMode.EditProduct;
            newDlg.Owner = this;
            newDlg.OldKey = (Product)listProdKeys.SelectedItem;
            newDlg.ShowDialog();

            if (newDlg.NewProduct != null && !String.IsNullOrEmpty(newDlg.NewProduct.Name))
            {
                foreach (ProductKeyManager.DB.Key code in newDlg.OldKey.Keys)
                {
                    db.Keys.DeleteOnSubmit(code);

                }
                db.SubmitChanges();

                db.Products.DeleteOnSubmit(newDlg.OldKey);
                db.Products.InsertOnSubmit(newDlg.NewProduct);
                db.SubmitChanges();

                SetView();
            }
        }

        /// <summary>
        /// Called when the Delete button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void DeleteButtonClicked(object sender, RoutedEventArgs e)
        {
            if (NewMessageBox.ShowYesNoDialog(this, this.LoadStringResource("DeleteDialogTitle"),
                string.Format(this.LoadStringResource("DeleteDialogInstruction"), ((Product)listProdKeys.SelectedItem).Name),
                this.LoadStringResource("DeleteDialogContent")) == TaskDialogResults.Yes)
            {
                db.Products.DeleteOnSubmit((Product)listProdKeys.SelectedItem);
                db.SubmitChanges();

                SetView();
            }
        }

        /// <summary>
        /// Called when the Exit menu item is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void FileMenuExitClicked(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Checks the database for a product.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="found">the product if found. (out)</param>
        /// <returns>Whether or not the product was found</returns>
        private bool DbHasProduct(Product entity, out Product found)
        {
            try
            {
                Product results = db.Products.Single(p => p.Name == entity.Name);
                found = results;
                return true;
            }
            catch (Exception)
            {
                found = null;
                return false;
            }
        }

        /// <summary>
        /// Checks whether the product has a key
        /// </summary>
        /// <param name="prod">The product.</param>
        /// <param name="key">The key we are looking for</param>
        /// <returns>Whether or not the product has the key</returns>
        private static bool ProdHasKey(Product prod, ProductKeyManager.DB.Key key)
        {
            try
            {
                ProductKeyManager.DB.Key results = prod.Keys.Single(k => k.KeyCode == key.KeyCode && k.AllocatedTo == key.AllocatedTo);
                return results == null;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Merges the keys.
        /// </summary>
        /// <param name="importkeys">The importkeys.</param>
        private void MergeKeys(IEnumerable<Product> importkeys)
        {
            foreach (Product prod in importkeys)
            {
                Product found;
                if (DbHasProduct(prod, out found))
                {
                    foreach (ProductKeyManager.DB.Key key in prod.Keys)
                    {
                        if (!ProdHasKey(found, key))
                        {
                            found.Keys.Add(new ProductKeyManager.DB.Key { KeyCode = key.KeyCode, AllocatedTo = key.AllocatedTo });
                        }
                    }
                }
                else
                {
                    db.Products.InsertOnSubmit(prod);
                }
            }
            db.SubmitChanges();
        }

        /// <summary>
        /// Called when the Import Product Key Manager XML button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void FileMenuImportProductKeyManagerXmlClicked(object sender, RoutedEventArgs e)
        {
            OpenFileDialog opendlg = new OpenFileDialog();
            opendlg.DefaultExt = "xml";
            opendlg.Filter = "Xml files (*.xml)|*.xml";
            if ((bool)opendlg.ShowDialog())
            {
                Mouse.OverrideCursor = Cursors.Wait;
                MergeKeys(XML.XmlHandler.ImportProductKeyManagerXml(new Uri(opendlg.FileName)));
            }
            SetView();
            Mouse.OverrideCursor = Cursors.Arrow;
        }

        /// <summary>
        /// Called when the About button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void MenuHelpAboutClicked(object sender, RoutedEventArgs e)
        {
            AboutDialog helpWin = new AboutDialog();
            helpWin.Owner = this;
            helpWin.ShowDialog();
        }

        /// <summary>
        /// Called when the Purge DB button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void ToolsPurgeDBClicked(object sender, RoutedEventArgs e)
        {
            if(NewMessageBox.ShowYesNoDialog(this, this.LoadStringResource("PurgeDBDialogTitle"),
                this.LoadStringResource("PurgeDBDialogInstruction"),
                this.LoadStringResource("PurgeDBDialogContent")) == TaskDialogResults.Yes)
            {
                    db.Products.DeleteAllOnSubmit(products);
                    db.SubmitChanges();
                    SetView();
            }
        }

        /// <summary>
        /// Called on keypress in the search box. We are looking for either the return key or the escape key to 
        /// search or cancel search.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
        private void SearchKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Return)
            {
                chkSearch.IsChecked = !chkSearch.IsChecked;
                if ((bool)chkSearch.IsChecked)
                {
                    OnSearch(sender, null);
                }
                else
                {
                    OnUnSearch(sender, null);
                }
            }
            if (e.Key == System.Windows.Input.Key.Escape)
            {
                if ((bool)chkSearch.IsChecked)
                {
                    chkSearch.IsChecked = false;
                    OnUnSearch(sender, null);
                }
            }
        }

        /// <summary>
        /// Called on keypress in the product list box. We are looking for the delete key to delete selected keys.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
        private void ListBoxKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Delete)
            {
                DeleteButtonClicked(sender, (RoutedEventArgs)e);
            }
        }

        /// <summary>
        /// Handles the SelectionChanged event of the listProdKeys control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void listProdKeys_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            bool isSelected = false;
            if(listProdKeys.SelectedIndex > -1)
            {
                isSelected = true;
            }

            MenuEdit.IsEnabled = isSelected;
            toolbEdit.IsEnabled = isSelected;
        }

        /// <summary>
        /// Handles the DoubleClicked event of the listProdKeys control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void listProdKeys_DoubleClicked(object sender, RoutedEventArgs e)
        {
            if (listProdKeys.SelectedIndex > -1)
            {
                ProductDialog viewWindow = new ProductDialog();
                viewWindow.Mode = DialogMode.ViewProduct;
                viewWindow.OldKey = (Product)listProdKeys.SelectedItem;
                viewWindow.Owner = this;
                viewWindow.ShowDialog();
            }
        }

        private void FileMenuExportProductKeyManagerXmlClicked(object sender, RoutedEventArgs e)
        {
            bool GenerateStyleSheet = PromptExportXsl();

            SaveFileDialog save = new SaveFileDialog();
            save.DefaultExt = "xml";
            save.Filter = "Xml files (*.xml)|*.xml";
            if ((bool)save.ShowDialog())
            {
                Mouse.OverrideCursor = Cursors.Wait;
                string xml = XML.XmlHandler.ExportProductKeyManagerXml(products, GenerateStyleSheet, save.SafeFileName);
                SaveProductKeyXml(GenerateStyleSheet, save, xml, Properties.Settings.Default.ProductKeyManagerXmlStylesheet);
            }
            Mouse.OverrideCursor = Cursors.Arrow;
        }

        /// <summary>
        /// Saves the product key XML.
        /// </summary>
        /// <param name="GenerateStyleSheet">if set to <c>true</c> [generate style sheet].</param>
        /// <param name="save">The save.</param>
        /// <param name="xml">The XML.</param>
        /// <param name="xmlStylesheet">The XML stylesheet.</param>
        private static void SaveProductKeyXml(bool GenerateStyleSheet, SaveFileDialog save, string xml, string xmlStylesheet)
        {
            File.WriteAllText(save.FileName, xml, Encoding.Default);
            if (GenerateStyleSheet)
            {
                if (File.Exists(save.FileName + ".xsl"))
                {
                    if (MessageBox.Show("'" + save.FileName + ".xsl?' already exists." + Environment.NewLine + "Do you want to replace it?", "Save As", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                    {
                        File.WriteAllText(save.FileName + ".xsl", xmlStylesheet, Encoding.Default);
                    }
                }
                else
                {
                    File.WriteAllText(save.FileName + ".xsl", xmlStylesheet, Encoding.Default);
                }
            }
        }

        /// <summary>
        /// Prompts the export XSL.
        /// </summary>
        /// <returns></returns>
        private bool PromptExportXsl()
        {
            bool GenerateStyleSheet;
            if (Properties.Settings.Default.EnableXslExport && Properties.Settings.Default.PromptXsl)
            {
                try
                {
                    GenerateStyleSheet = TaskDialogHelper.ShowDialog(this, "Generate Stylesheet?", "Would you like a XSL stylesheet generated?",
                        "This will make the results easier to view results when opened in some applications such as Internet Explorer and FireFox.", TaskDialogButtons.Yes | TaskDialogButtons.No,
                        TaskDialogIcon.Information) == TaskDialogResults.Yes;
                }
                catch (Exception)
                {
                    GenerateStyleSheet = MessageBox.Show("Would you like a XSL stylesheet generated? This will make the results easier to view results when opened in some applications such as Internet Explorer and FireFox.", "Generate Stylesheet?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;
                }
            }
            else if (Properties.Settings.Default.EnableXslExport && !Properties.Settings.Default.PromptXsl)
            {
                GenerateStyleSheet = true;
            }
            else
            {
                GenerateStyleSheet = false;
            }
            return GenerateStyleSheet;
        }

        private void FileMenuExportMsdnXmlClicked(object sender, RoutedEventArgs e)
        {
            bool GenerateStyleSheet = PromptExportXsl();

            SaveFileDialog save = new SaveFileDialog();
            save.DefaultExt = "xml";
            save.Filter = "Xml files (*.xml)|*.xml";
            if ((bool)save.ShowDialog())
            {
                Mouse.OverrideCursor = Cursors.Wait;
                string xml = XML.XmlHandler.ExportMsdnXml(products, GenerateStyleSheet, save.SafeFileName);
                SaveProductKeyXml(GenerateStyleSheet, save, xml, Properties.Settings.Default.MsdnXmlStyleSheet);
            }
            Mouse.OverrideCursor = Cursors.Arrow;
        }

        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            db.Dispose();
        }

        #endregion

        /// <summary>
        /// Handles the Closing event of the Window control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        private void Window_Closing(object sender, CancelEventArgs e)
        {
            SaveToolbarLocations();
        }

        /// <summary>
        /// Handles the Click event of the LockToolBars control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void LockToolBars_Click(object sender, RoutedEventArgs e)
        {
            bool isLocked = ((MenuItem)sender).IsChecked;
            this.toolTrayBottom.IsLocked = isLocked;
        }

        /// <summary>
        /// Handles the Click event of the ToolsSettings control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void ToolsSettings_Click(object sender, RoutedEventArgs e)
        {
            Settings settingsWindow = new Settings();
            settingsWindow.ShowDialog();
            LoadToolbarLocations();
            SetView();
        }
    }
}